﻿#region License Information
// Copyright (c) 2005 - 2009, Allan Spartacus Mangune (allan@owlpal.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, 
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list 
//   of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of 
//   conditions and the following disclaimer in the documentation and/or other materials provided 
//   with the distribution.
//
// * Neither the name of Owlpal nor the names of its contributors may be used to endorse or 
//   promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 
// BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
#endregion

using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.Linq;
using System.Web;
using Owlpal.Models;
using Owlpal.Models.Repositories;
using Owlpal.Models.Repositories.Factories;

namespace Owlpal.Models.Repositories
{
    /// <summary>
    /// 
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class Repository<T> : IRepository<T> where T : class
    {
        /// <summary>
        /// 
        /// </summary>
        protected IDataContextFactory dataContextFactory;

        /// <summary>
        /// 
        /// </summary>
        public Repository()
        { 
            
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataContextFactory"></param>
        public Repository(IDataContextFactory dataContextFactory)
        {
            this.dataContextFactory = dataContextFactory;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public IEnumerable<T> FindAll(Func<T, bool> expression)
        {
            throw new System.NotImplementedException();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public T First(Func<T, bool> expression)
        {
            ObjectQuery<T> query = new ObjectQuery<T>(typeof(T).ToString(), 
                this.dataContextFactory.Context);
            return query.Where(expression).First();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public T FirstOrDefault(Func<T, bool> expression)
        {
            string name = typeof(T).ToString().Remove(0, 14);
            ObjectQuery<T> query = new ObjectQuery<T>(typeof(T).ToString().Remove(0, 14), 
                this.dataContextFactory.Context);
            return query.Where(expression).FirstOrDefault();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        public virtual void MarkForDeletion(T entity)
        {
            throw new System.NotImplementedException();        
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual T CreateInstance(T entity)
        {
            this.dataContextFactory.Context.AddObject(typeof(T).ToString(), entity);
            return entity;
        }

        /// <summary>
        /// 
        /// </summary>
        public virtual void SaveChanges()
        {
            this.dataContextFactory.Context.SaveChanges();
        }
    }
}
